package main

import (
	"fmt"
	"io"
	"net/http"
	"sort"
	"strconv"
	"strings"
)

const SERVER = "0.0.0.0"
const PORT = "9001"

func main() {
	http.ListenAndServe(SERVER+":"+PORT, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		var formNumbers = req.FormValue("numbers")
		var result string
		var numbers []float64

		if req.Method == "POST" {
			strNumbers := strings.FieldsFunc(formNumbers, func(c rune) bool { return c == ',' || c == ' ' })
			numbers = make([]float64, 0, len(strNumbers))

			var sum float64 = 0
			for _, strNum := range strNumbers {
				num, err := strconv.ParseFloat(strNum, 64)
				if err == nil {
					numbers = append(numbers, num)
					sum += num
				}
			}
			numsLen := len(numbers)
			mean := sum / float64(numsLen)

			sort.Float64s(numbers)
			var median float64
			if numsLen%2 == 1 {
				median = numbers[numsLen/2]
			} else {
				median = (numbers[numsLen/2-1] + numbers[numsLen/2]) / 2
			}

			result = `<table border="1">
				<tr>
				<td colspan="2" style="text-align:center;font-weight:bold">Results</td>
				</tr>
				<tr>
					<td>Numbers</td>
					<td>` + fmt.Sprint(numbers) + `</td>
				</tr>
				<tr>
					<td>Count</td>
					<td>` + fmt.Sprint(numsLen) + `</td>
				</tr>
				<tr>
					<td>Mean</td>
					<td>` + fmt.Sprintf("%0.6f", mean) + `</td>
				</tr>
				<tr>
					<td>Median</td>
					<td>` + fmt.Sprintf("%0.6f", median) + `</td>
				</tr>
			</table>`
		}

		html := `<html>
			<head><title>Statistics</title></head>
			<body>
				<h1>Statistics</h1>
				<p>Computes basic statistics for a given list of numbers</p>

				<form method="POST">
					Numbers (comma or space-separated):<br/>
					<input type="text" size="40" name="numbers" value="` + formNumbers + `" /><br/>
					<input type="submit" value="Calculate" />
				</form>

				` + result + `
			</body>
		</html>`

		io.WriteString(w, html)
	}))
}
